import * as XLSX from 'xlsx'
import axios from 'axios'
import store from '@/assets/scripts/store'
import { toHump } from '@/assets/scripts/tools/utils'
import { getRegs } from '@/assets/scripts/formats/regs.js'
// 引入字典
import CONST from '@/assets/scripts/const.js'

// 展示类型 code、value、codeValue
export const TYPE_SHOW_CODE = 'code'
export const TYPE_SHOW_VALUE = 'value'
export const TYPE_SHOW_CODEVALUE = 'codeValue'
export const TYPE_SHOW_ARRAY = 'array'
// 哪些字典需要请求单独的表格
export const REF_DICT_UNITE = { table: 'Dict', name: '字典', fields: ['code', 'value'], param: 'category', showLabel: 'value', showValue: 'code' }
export const REF_DICT_SETTLEMENT = { table: 'zj_dict', name: '结算单字典', fields: ['zj_code', 'zj_value'], param: 'zj_field_name', showLabel: 'zj_value', showValue: 'zj_code' }
export const REF_DICT_ALONE = [
  // fields需要模糊匹配的字段，
  // param参数名，
  // dict参数值，
  // table去哪个表查，
  // showLabel展示时取哪个字段作为label，
  // showValue展示时取哪个字段作为value
  // {dict: 'OperationCategory', table: 'icd_9', name: '手术类别', fields: [], param: '', showLabel: 'value', showValue: 'code'},
  { dict: 'ProvinceDict', table: 'ProvinceDict', name: '省' },
  { dict: 'ProvinceCity', table: 'ProvinceDict', name: '市', fields: ['city', 'code', 'pinyin'], param: '', showLabel: 'city', showValue: 'code' },
  { dict: 'ProvinceArea', table: 'ProvinceDict', name: '区', fields: ['district', 'code', 'pinyin'], param: '', showLabel: 'district', showValue: 'code' },
  { dict: 'Depart', table: 'Depart', name: '科室', fields: ['depName', 'depCode', 'inputCode'], param: { depType: '3' }, showLabel: 'depName', showValue: 'depCode' },
  { dict: 'DepartName', table: 'Depart', name: '科室', fields: ['depName', 'depCode', 'inputCode'], param: { depType: '3' }, showLabel: 'depName', showValue: 'depName' },
  { dict: 'DepUserNurse', table: 'Doctor', name: '护士', fields: ['docName', 'docCode', 'inputCode'], param: '', showLabel: 'docName', showValue: 'docCode' },
  { dict: 'MedGroupDepart', table: 'Depart', name: '医疗科室', fields: ['depName', 'depCode', 'inputCode'], param: { depType: '10' }, showLabel: 'depName', showValue: 'depCode' },
  { dict: 'MedGroupDepSettlement', table: 'Depart', name: '医疗科室', fields: ['catyName', 'catyCode', 'inputCode'], param: { depType: '3' }, showLabel: 'catyName', showValue: 'catyCode' },
  { dict: 'MedGroupDict', table: 'medGroupDict', name: '医疗组', fields: ['docName', 'docCode', 'medGroupCode', 'medGroupValue'], param: '', showLabel: 'docName', showValue: 'docCode' },
  { dict: 'DepUserDoctor', table: 'Doctor', name: '医生', fields: ['docName', 'docCode', 'inputCode'], extendField: ['docProfes'], param: '', showLabel: 'docName', showValue: 'docCode' },
  { dict: 'DepUserDoctorSettlement', table: 'Doctor', name: '医生', fields: ['docName', 'standardNo', 'inputCode'], param: '', showLabel: 'docName', showValue: 'standardNo' },
  { dict: 'DepUserCoder', table: 'Doctor', name: '编码员', fields: ['docName', 'docCode', 'inputCode'], param: '', showLabel: 'docName', showValue: 'docCode' },
  { dict: 'UserPage', table: 'UserPage', name: '系统用户', fields: ['staffName', 'loginName', 'phoneNumber'], param: '', showLabel: 'staffName', showValue: 'loginName' },
  { dict: 'UserPageCoder', table: 'UserPage', name: '系统用户编码员', fields: ['staffName', 'loginName', 'phoneNumber'], param: { isCoder: true }, showLabel: 'staffName', showValue: 'loginName' },
  { dict: 'Medicine', table: 'gmywdm_jxyb', name: '过敏药物', fields: ['YPMC', 'BZBM', 'SRM1'], param: '', showLabel: 'YPMC', showValue: 'YPMC' },
  { dict: 'M码', table: 'mdm', name: '病理诊断', fields: ['MDMM', 'MBZM', 'SRM1'], param: '', showLabel: 'MDMM', showValue: 'MBZM' },
  { dict: 'MZFS', table: 'mzfs_yb_v1', name: '麻醉方式', fields: ['code', 'value', 'pinyin'], param: '', showLabel: 'value', showValue: 'code' },
  { dict: 'AnesthesiaSettlement', table: 'zj_dict', name: '麻醉方式', fields: ['zj_code', 'zj_value', 'pinyin'], param: { 'zj_field_name': 'anst_mtd_code' }, showLabel: 'zj_value', showValue: 'zj_code' },
  { dict: 'IncisionHealingGrade', table: 'zj_dict', name: '切口愈合等级', fields: ['zj_code', 'zj_value', 'pinyin'], param: { 'zj_field_name': 'sinc_heal_lv_code' }, showLabel: 'zj_value', showValue: 'zj_code' },
  { dict: 'EDM', table: 'edm', name: '损伤中毒', fields: ['EBZM', 'EDMM'], param: '', showLabel: 'EDMM', showValue: 'EBZM' },
  { dict: 'ZYZDDM', table: 'icd_10_chinese', name: '诊断编码', fields: ['value', 'code', 'pinyin'], param: '', showLabel: 'value', showValue: 'code' },
  { dict: 'ZYZDZZ', table: 'zyzhdm', name: '诊断编码', fields: ['value', 'code', 'pinyin'], param: '', showLabel: 'value', showValue: 'code' },
  { dict: 'ICD-10-Edit', http: '/icd_code/query_yb_icd_10', table: 'icd_10', name: '诊断编码', fields: ['name', 'code'], param: '', showLabel: 'name', showValue: 'code' },
  { dict: 'ICD-9-CM3-Edit', http: '/icd_code/query_yb_icd_9', table: 'icd_9', name: '手术编码', fields: ['name', 'code'], param: '', showLabel: 'name', showValue: 'code' },
  { dict: 'ICD-10', table: 'icd_10', name: '诊断编码', fields: ['value', 'code', 'pinyin'], param: '', showLabel: 'value', showValue: 'code' },
  { dict: 'ICD-9-CM3', table: 'icd_9', name: '手术编码', fields: ['value', 'code', 'pinyin'], param: '', showLabel: 'value', showValue: 'code' },
  { dict: 'ICD-10-YB', table: 'icd_10', name: '诊断编码', fields: ['yb_name', 'yb_code', 'pinyin'], param: '', showLabel: 'yb_name', showValue: 'yb_code' },
  { dict: 'ICD-9-CM3-YB', table: 'icd_9', name: '手术编码', fields: ['yb_name', 'yb_code', 'pinyin'], param: '', showLabel: 'yb_name', showValue: 'yb_code' },
  { dict: 'DRGROUP', table: 'drg_group_value', name: 'DRG分组', fields: ['drg_name', 'drg_code'], param: '', showLabel: 'drg_name', showValue: 'drg_code' },
  { dict: 'IcuType', table: 'zj_dict', name: '重症监护病房类型', fields: ['zj_code', 'zj_value'], param: { 'zj_field_name': 'icu_type' }, showLabel: 'zj_value', showValue: 'zj_code' },
  { dict: 'BldCat', table: 'zj_dict', name: '输血品种', fields: ['zj_code', 'zj_value'], param: { 'zj_field_name': 'bld_cat' }, showLabel: 'zj_value', showValue: 'zj_code' },
  { dict: 'MedChrgitmType', table: 'zj_dict', name: '医疗收费项目类别', fields: ['zj_code', 'zj_value'], param: { 'zj_field_name': 'med_chrgitm_type' }, showLabel: 'zj_value', showValue: 'zj_code' },
  { dict: 'outDiagnosisStateSettlement', table: 'zj_dict', name: '入院病情', fields: ['zj_code', 'zj_value'], param: { 'zj_field_name': 'adm_dise_cond_code' }, showLabel: 'zj_value', showValue: 'zj_code' },
  {
    dict: 'IsICU',
    name: '重症监护',
    table: '',
    noapi: true, // 没有数据字典接口
    tips: [
      { label: '无', value: '0' },
      { label: '有', value: '1' }
    ]
  }
]

function handleFmtMedp (data = []) {
  const dep = []
  data.map(ditem => {
    const index = dep.findIndex(pitem => {
      return pitem.value === ditem.medGroupCode
    })
    const child = {
      value: ditem.docCode,
      label: ditem.docName,
      r: ditem,
      type: 'doctor'
    }
    if (index > -1) {
      dep[index].children.push(child)
    } else {
      dep.push({
        value: ditem.medGroupCode,
        label: ditem.medGroupValue,
        type: 'clinic',
        children: [child]
      })
    }
  })
  return dep
}

function handleFmtAddr (data = []) {
  return data.map(pro => {
    pro.value = pro.code
    pro.label = pro.province
    pro.children = pro.cities.map(city => {
      city.value = city.code
      city.label = city.city
      city.children = city.districts.map(district => {
        district.value = district.code
        district.label = district.district
        return district
      })
      delete city.districts
      return city
    })
    delete pro.cities
    return pro
  })
}

// 字段分类
export const FILE_CATE = {
  base: '患者信息',
  diagnosis: '诊断相关',
  operationByPerson: '手术按人',
  operationByGroup: '手术按组',
  depart: '科室相关',
  fee: '费用相关',
  pathologyRecord: '病理按人',
  pathologyRecordByGroup: '病理按组',
  dischargeSummary: '出院小结',
  doctor: '医生相关',
  province: '省五项',
  inhospital: '住院信息'
}
// 读取role文件数据
export async function readRuleXlsx (getSelectDictList) {
  return new Promise(async (resolve) => {
    var url = 'static/rule.xlsx' // 放在public目录下的文件可以直接访问
    // 读取二进制excel文件,参考https://github.com/SheetJS/js-xlsx#utility-functions
    const res = await axios.get(url, { responseType: 'arraybuffer' })
    if (res && res.data) {
      var data = new Uint8Array(res.data)
      const workbook = XLSX.read(data, {
        type: 'array'
      }) // 读取数据
      const wsname = workbook.SheetNames[0] // 取第一张表
      const ws = XLSX.utils.sheet_to_json(workbook.Sheets[wsname])
      // 格式化数据
      const rules = {}
      const collectionList = {}
      for (let i = 0; i < ws.length; i++) {
        const item = ws[i]
        // 根据商户类型 存储对应的规则
        // 下划线转驼峰
        for (const key in item) {
          const value = item[key]
          delete item[key]
          item[toHump(key)] = value
        }
        // 格式化字段显示和保存格式
        const format = function (item) {
          // 组装rule
          let regExpress = ''
          let type = ''
          let typeSave = TYPE_SHOW_VALUE // 保存
          let typeShow = TYPE_SHOW_VALUE // 下拉显示
          let typeSelect = TYPE_SHOW_VALUE // 下拉选中
          let dict = ''
          const dictRegs = getRegs()
          if (item.type === 'str') {
            type = 'input'
          } else if (item.type === 'int') {
            type = 'input'
            regExpress = dictRegs.intzero
          } else if (item.type === 'date' || item.type === 'datetime' || item.type === 'datetimerange') {
            type = item.type
          } else if (item.type === 'dict') {
            type = 'select-remote'
          } else if (item.type === 'cascader-addr') {
            type = 'cascader-addr'
          } else if (item.type === 'cascader-medp') {
            type = 'cascader-medp'
          } else if (item.type === 'money') {
            type = 'input'
            regExpress = dictRegs.money
          }
          if (item.feDict) {
            if (type !== 'cascader-addr' && type !== 'cascader-medp') {
              type = 'select-remote'
              typeSave = TYPE_SHOW_CODEVALUE
              typeShow = TYPE_SHOW_CODEVALUE
              typeSelect = TYPE_SHOW_CODEVALUE
              if (item.type !== 'dict') {
                typeSave = TYPE_SHOW_VALUE
              }
              if (item.type === 'array') {
                typeSave = TYPE_SHOW_ARRAY
              }
              if (item.typeSave) {
                typeSave = item.typeSave
              }
              if (item.typeShow) {
                typeShow = item.typeShow
              }
            }
            dict = judgeDictUnite(item.feDict)
          }
          if (item.type === 'array') {
            type = 'array'
          }
          // 如果是中医院 国籍保存成字符串
          if (store.state.storeMch && store.state.storeMch.HosType === CONST.hosTypeCh) {
            if (item.fieldName === 'country') {
              typeSave = TYPE_SHOW_VALUE
            }
          }
          if (item.settlementFieldName) {
            typeSave = item.typeSave || typeSave
          }
          return { type, regExpress, typeSave, dict, typeShow, typeSelect }
        }
        // rule 格式
        if (item.fieldName) {
          const formatData = format(item)
          rules[item.fieldName] = {
            label: item.hqmsFieldNameCn, // 字段名
            keyCode: item.fieldName, // 字段值
            type: formatData.type, // 显示类型 select-remote远程搜索 input简单输入 date日期 datetime时间 array数组
            array: [], // 针对array
            isRequired: item.required, // 是否必须
            regExpress: formatData.regExpress, // 针对input：校验规则
            cate: item.feDict, // 针对select-remote：字典在表中的分类
            typeDb: item.type, // 字段在数据库中的类型
            typeSelect: formatData.typeSelect, // 针对select-remote：保存类型 code、value、codeValue  下拉框里的展示
            typeShow: formatData.typeShow, // 针对select-remote：保存类型 code、value、codeValue  选中之后的展示
            typeSave: formatData.typeSave, // 针对select-remote：保存类型 code、value、codeValue  最终保存
            dict: formatData.dict, // 针对select-remote：假如是字典类型 属于哪个字典哪个类型 REF_DICT_ALONE的对象
            isHide: item.isHide, // 保存时是否隐藏 针对疾病数组和手术数组
            isHideSort: item.isHideSort, // 是否隐藏排序
            tips: item.tips || [], // 提示下拉框 在病案编辑用到
            isTips: item.isTips, // 是否显示提示
            isSearchParent: item.isSearchParent, // 诊断 和 手术 搜索时用到
            isHideCpx: item.isHideCpx,
            original: item, // 原始数据 excel中到数据
            settlementFieldName: item.settlementFieldName // 对应表中settlement_field_name字段，对应结算单字典中zj_field_name字段
          }
          // 如果是字典表Dict的值，需要默认tip
          const dataForm = rules[item.fieldName]
          // console.log('dataForm', dataForm)
          if (dataForm.isTips) {
            let tips = []
            if (dataForm.dict.tips && dataForm.dict.tips.length > 0) {
              tips = dataForm.dict.tips
            }
            let key = (dataForm.dict.table || '') + '_' + (item.fieldName || '')
            if (dataForm.dict.param) {
              key = key + '_' + dataForm.cate
            }
            if (dataForm.dict.table && !collectionList[key]) {
              tips = await handleFmtHttp(dataForm, getSelectDictList)
            }
            if (tips && tips.length > 0) {
              collectionList[key] = tips
            }
            // 对应的字典值是什么
            rules[item.fieldName].dictKey = key
          }
          // 结算单字典生成
          if (dataForm.settlementFieldName) {
            const keySettl = `[zj_dict]_[${item.fieldName}]_[${dataForm.settlementFieldName}]`
            const tipSettl = await handleFmtHttp(dataForm, getSelectDictList, true)
            collectionList[keySettl] = tipSettl
            // 结算单字段settlement_field_name，对应zj_dict表中zj_field_name
            rules[item.fieldName].dictSettleKey = keySettl
          }
        }
      }
      // 过滤数据
      for (const key in rules) {
        if (rules[key].type === 'array') {
          const array = []
          const list = rules[key].cate.split(',')
          for (let j = 0; j < list.length; j++) {
            array.push(rules[list[j]])
          }
          rules[key].array = array
        }
      }
      // console.log('collectionList', collectionList)
      // console.log('rules', rules)
      // 存储到store(区分version 和 医院类型)
      store.commit('SET_DICTIONARY', collectionList)
      store.commit('SET_RULE', rules)
    }
    resolve()
  })
}

export function handleFmtHttp (dataForm, fnHttp, isSettlement) {
  return new Promise(async (resolve) => {
    // 结算单取字典内容
    let tips = []
    const dataDict = isSettlement ? Object.assign({}, dataForm.dict, REF_DICT_SETTLEMENT) : dataForm.dict
    // 表名, 默认字典表
    const collection = dataDict.table
    // 需要模糊匹配的字段
    const fields = dataDict.fields
    // 请求参数
    let data = {
      pageSize: 0
    }
    // 如果param有值，需要将cate赋值
    if (dataDict.param) {
      if (dataDict.param.constructor === Object) {
        data = Object.assign({}, data, dataDict.param)
      } else {
        // 如果是结算单，query中的值传zj_field_name：取excel表中settlement_field_name字段
        data[dataDict.param] = isSettlement ? dataForm.settlementFieldName : dataForm.cate
      }
    }
    // 排序
    const sort = {}
    if (dataDict.showValue) {
      sort[dataDict.showValue] = 1
    }
    let res
    if (dataDict.http) {
      res = await fnHttp(dataDict.http, collection, Object.assign({}, data, { sort: [sort] }), '', fields)
    } else {
      res = await fnHttp(collection, Object.assign({}, data, { sort: [sort] }), '', fields)
    }
    if (res && res.data && res.data.records) {
      if (dataForm.type === 'cascader-medp') {
        // 按医疗科室格式化
        tips = handleFmtMedp(res.data.records)
      } else if (dataForm.type === 'cascader-addr') {
        tips = handleFmtAddr(res.data.records)
      } else {
        res.data.records.map(r => {
          tips.push({
            id: r.id,
            label: r[dataDict.showLabel],
            value: r[dataDict.showValue]
          })
        })
      }
    }
    resolve(tips)
  })
}

// 将REF_DICT_ALONE转换为Object
export function transDictAlone () {
  const dataNew = {}
  REF_DICT_ALONE.map(item => {
    dataNew[item.dict] = item
  })
  return dataNew
}

// 判断refDict是否存在字典表、还是单独表
export function judgeDictUnite (refDict) {
  return transDictAlone()[refDict] || REF_DICT_UNITE
}
